import Component from "../Component";
import ccclass = cc._decorator.ccclass;
import property = cc._decorator.property;

@ccclass()
export class FollowComponent extends Component {

    private readonly MSG_FOLLOW_CLICK: string = "__follow_msg";
    // 跟随谁.
    @property({displayName: "跟随源"})
    private follow: string = "";

    // 被跟随.
    @property({displayName: "跟随标识"})
    private followed: string = "";

    private FOLLOW_BOUNDS = {};

    public onShow() {
        this.FOLLOW_BOUNDS = FollowCompHelper.get().FOLLOW_BOUNDS;
        this._initFollowData();
    }

    public onHide() {
        if (this.followed.length > 0) {
            if (this.FOLLOW_BOUNDS[this.followed] && this.FOLLOW_BOUNDS[this.followed].comp === this) {
                delete this.FOLLOW_BOUNDS[this.followed];
            }
        }
    }

    public listen(): string[] {
        return [this.MSG_FOLLOW_CLICK];
    }

    public handleMessage(message: string, args: any[]): boolean {
        switch (message) {
            case this.MSG_FOLLOW_CLICK: {
                const follow = args[0];
                if (follow && this.followed === follow) {
                    this.performClick(this.node);
                }
                break;
            }
        }
        return false;
    }

    public onClick() {
        this.performClick(this);
    }

    // 初始化跟随系统.
    private _initFollowData() {
        if (this.follow.length > 0) {
            this.setClickListener(this.node, () => {
                this.sendMessage(this.MSG_FOLLOW_CLICK, [this.follow])
            });
            if (this.FOLLOW_BOUNDS[this.follow]) {
                const bounding = this.FOLLOW_BOUNDS[this.follow].bound as cc.Rect;
                if (bounding) {
                    this.node.position = this.node.parent.convertToNodeSpaceAR(bounding.center);
                }
            }
        }

        if (this.followed.length > 0) {
            this.FOLLOW_BOUNDS[this.followed] = {comp: this, bound: this.node.getBoundingBoxToWorld()}
        }
    }
}

/**
 * 针对follow组件的一个辅助类.用来获取某名称对应注册的组件节点的,以便能够触发一些操作.
 */
export class FollowCompHelper {

    public static get(): FollowCompHelper {
        return this.instance;
    }

    private static instance: FollowCompHelper = new FollowCompHelper();
    // 需要记录待跟随的组件节点的位置等信息.
    public readonly FOLLOW_BOUNDS = {};

    public getFollowedComponent(key: string): { comp: FollowComponent, bound: cc.Rect; } {
        return this.FOLLOW_BOUNDS[key];
    }
}